#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <string>
#include "LockGuard.hpp"

using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int tickets = 100;

/*
class threadData
{
public:
    threadData(int number, pthread_mutex_t* mutex) 
        :_threadname("Thread" + to_string(number))
        ,_mutex(mutex)
    {}

public:
    string _threadname;
    pthread_mutex_t* _mutex;
};

void* GetTickets(void* arg)
{
    threadData* td = static_cast<threadData*>(arg);

    while (true)
    {
        pthread_mutex_lock(td->_mutex);
        if (tickets > 0)
        {
            usleep(10000); 
            cout << td->_threadname << " got a ticket : " << tickets << endl;  
            tickets--;
            pthread_mutex_unlock(td->_mutex);   //票抢到，需要解锁
            
            usleep(10000);  //模拟票的处理时间
            
        }
        else
        {
            pthread_mutex_unlock(td->_mutex);   //票抢完了，需要解锁
            break;
        }
    }

    cout << td->_threadname << " : quit" << endl;
    return nullptr;
}



int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);
    vector<pthread_t> tids;
    vector<threadData*> tds;
    for (int i = 0; i < 5; i++)
    {
        pthread_t tid;
        threadData* td = new threadData(i, &mutex);
        tds.push_back(td);
        pthread_create(&tid, nullptr, GetTickets, td);
        tids.push_back(tid);
    }

    for (int i = 0; i < tids.size(); i++)
    {
        pthread_join(tids[i], nullptr); //原型：int pthread_join(pthread_t thread, void **retval);
        delete tds[i];
    } 
    pthread_mutex_destroy(&mutex);
    return 0;
}
*/

class threadData
{
public:
    threadData(int number) 
        :_threadname("Thread" + to_string(number))
    {}

public:
    string _threadname;
};

void* GetTickets(void* arg)
{
    threadData* td = static_cast<threadData*>(arg);
    while (true)
    {
        {
            LockGuard Mutex(&mutex);    //构造函数内部会调用Lock（）    
           
            if (tickets > 0)
            {   
                usleep(10000); 
                cout << td->_threadname << " got a ticket : " << tickets << endl;  
                tickets--;
            }
            else
            {
                break;
            }
        }
        usleep(10000);  //模拟票的处理时间

    }

    cout << td->_threadname << " : quit" << endl;
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;
    vector<threadData*> tds;
    for (int i = 0; i < 5; i++)
    {
        pthread_t tid;
        threadData* td = new threadData(i);
        tds.push_back(td);
        pthread_create(&tid, nullptr, GetTickets, td);
        tids.push_back(tid);
    }

    for (int i = 0; i < tids.size(); i++)
    {
        pthread_join(tids[i], nullptr); //原型：int pthread_join(pthread_t thread, void **retval);
        delete tds[i];
    } 
    return 0;
}